package com.tfswx.serialport.service;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

import java.nio.charset.Charset;

/**
 * @author ricky
 * @date 2021/7/19
 */
public class PrintService {

    private static Charset gbk = Charset.forName("GBK");

    public static void print(String content) {
        Print instance = Print.INSTANCE;
        int i;

        if (Platform.isWindows()) {
            i = instance.SetUsbportauto();
        } else {
            i = instance.SetDevname(3, "", 0);
        }

        if (i == 1) {
            throw new RuntimeException("未找到打印机");
        }
        i = instance.SetInit();
        if (i == 1) {
            throw new RuntimeException("打印机初始化失败，请检查打印机已连接！");
        }
        // 退纸80个单位
        byte[] tuizhi = new byte[]{0x1B, 0x4B, 80};
        instance.PrintTransmit(tuizhi, tuizhi.length);
        // 设置为中文模式
        instance.SetReadZKmode(0);
        // 设置左边距为20个单位
        instance.SetLeftmargin(20);
        // 打印内容
        byte[] bData = content.getBytes(gbk);
        instance.PrintTransmit(bData, bData.length);

        // 识别探缝
        instance.PrintMarkpositioncut();
        // 切纸
        instance.PrintCutpaper(1);
    }

    public interface Print extends Library {
        Print INSTANCE = (Print) Native.synchronizedLibrary(
                (Print) Native.loadLibrary("msprintsdk", Print.class)
        );

        /**
         * 设置设备名称(Linux)
         *
         * @param iDevtype
         * @param cDevname
         * @param iBaudrate
         * @return 0 成功 1 失败
         */
        int SetDevname(int iDevtype, String cDevname, int iBaudrate);

        /**
         * 自动查找USB设备端口名称。
         * <p>
         * 该接口仅适应于USB连接方式和打印机通信。
         *
         * @return
         */
        int SetUsbportauto();

        /**
         * 打印机初始化
         * <p>
         * 打开设备或端口连接打印机，初始化打印机，完成缓存的清空等工作。
         * <p>
         * 必须成功调用此接口后，才能使打印机工作。
         * <p>
         * 勿频繁调用此接口。
         * <p>
         * 需先调用SetDevname设置参数，如果未调用，则会从so所在的文件夹中查找
         * Config.ini文件，存在Config.ini文件的话，那么会从该文件中读取。文件格式见附录
         * 4.1.2 Linux配置。
         *
         * @return 0 成功 1 失败
         */
        int SetInit();

        /**
         * 转发指令(发送)
         * <p>将指令原样转给打印机。
         *
         * @param bData 指令
         * @param iLen  指令长度
         * @return 0 成功 1 失败
         */
        int PrintTransmit(byte bData[], int iLen);


        /**
         * 设置汉字模式
         * <p>
         * 设置汉字模式。
         *
         * @param mode 0 进入汉字模式 1 退出汉字模式
         * @return 0 成功 1 失败
         */
        int SetReadZKmode(int mode);

        /**
         * 设置左边界。
         *
         * @param iLeftspace 值范围 0-576 单位值 = 0.125
         * @return 0 成功 1 失败
         */
        int SetLeftmargin(int iLeftspace);

        /**
         * 检测黑标进纸到切纸位置
         * <p>
         * 黑标模式下检测黑标并进纸到切纸位置。
         * <p>
         * 切纸偏移量影响走纸距离。
         *
         * @return 0 成功 1 失败
         */
        int PrintMarkpositioncut();

        /**
         * 切纸。
         * <p>
         * int r = PrintCutpaper(0);
         *
         * @param iMode 0 全切 1 半切
         * @return 0 成功 1 失败
         */
        int PrintCutpaper(int iMode);
    }
}
